﻿#pragma once
#include<iostream>
#include<vector>
#include<memory>
using namespace std;

//模拟实现auto_ptr
namespace Auto_ptr {
	template<class T>
	class auto_ptr
	{
	public:
		auto_ptr(T* ptr)
			:_ptr(ptr)
		{}
		auto_ptr(auto_ptr<T>& sp)
			:_ptr(sp._ptr)
		{
			// 管理权转移
			sp._ptr = nullptr;
		}
		auto_ptr<T>& operator=(auto_ptr<T>& ap)
		{
				// 检测是否为⾃⼰给⾃⼰赋值
				if (this != &ap)
				{
					// 释放当前对象中资源
					if (_ptr)
						delete _ptr;
					// 转移ap中资源到当前对象中
					_ptr = ap._ptr;
					ap._ptr = NULL;
				}
			return *this;
		}
		~auto_ptr()
		{
			if (_ptr)
			{
				cout << "delete:" << _ptr << endl;
				delete _ptr;
			}
		}
		// 像指针⼀样使⽤
		T& operator*()
		{
			return *_ptr;
		}
		T* operator->()
		{
			return _ptr;
		}
	private:
		T* _ptr;
	};
}

//模拟实现unique_ptr
namespace Unique_ptr {
	template<class T>
	class unique_ptr
	{
	public:
		explicit unique_ptr(T* ptr)
			:_ptr(ptr)
		{}
		~unique_ptr()
		{
		       if (_ptr)
	    	{
				cout << "delete:" << _ptr << endl;
				delete _ptr;
		    }
		}
			// 像指针⼀样使⽤
			T& operator*()
		{
			return *_ptr;
		}
		T* operator->()
		{
			return _ptr;
		}
		//不支持拷贝的做法：
		unique_ptr(const unique_ptr<T>& sp) = delete;
		unique_ptr<T>& operator=(const unique_ptr<T>& sp) = delete;

		unique_ptr(unique_ptr<T>&& sp)  //移动构造
			:_ptr(sp._ptr)
		{
			sp._ptr = nullptr;
		}
		unique_ptr<T>& operator=(unique_ptr<T>&& sp) //移动赋值
		{
			delete _ptr;
			_ptr = sp._ptr;
			sp._ptr = nullptr;
		}
	private:
		T* _ptr;
	};
}

namespace Shared_ptr {
	template<class T>
	class shared_ptr {
	public:
		//默认构造与有参构造
		shared_ptr(T* ptr = nullptr)
			:_ptr(ptr), _pcount(new int(1)) {

		}

		//拷贝构造
		shared_ptr(const shared_ptr<T>& sp) {
			_ptr = sp._ptr;
			_pcount = sp._pcount;
			(*_pcount)++;
		}
		//拷贝赋值
		void operator=(const shared_ptr<T>& sp) {

			if (_ptr!=sp._ptr) {  //忽略自己给自己赋值
				// 和本身就已经共同管理一块空间的对象之间的赋值

				if ((*_pcount)-- == 1) {  //本对象原本是一块资源的最后管理者
					//(即使不是，也做到了减去了一个管理者)
					delete _ptr;          //释放原来的资源
					delete _pcount;
				}
				_ptr = sp._ptr;
				_pcount = sp._pcount;
				(*_pcount)++;
			}
		}

		~shared_ptr() {

			if ((*_pcount)-- == 1) {  //如果(*_pcount)==1,说明本对象
				//是某块资源的最后管理者，判断完后要--
				cout << "delete _ptr..." << endl;
				delete _ptr;
				delete _pcount;
			}
		}

		//使用：
		T& operator*() {
			return *_ptr;
		}
		T* operator->() {
			return _ptr;
		}
		T& operator[](size_t pos) {
			return _ptr[pos];
		}

	private:
		T* _ptr;
		int* _pcount;
	};

}